Version 1/060808 of Achievements by Mikael Segercrantz begins here. "A table-based way to assign scores for actions, rooms and objects." Chapter 1 - The objects Section 1(a) - Table of Achievements Table of Achievements message points used text a number a number Section 1(b) - Table of Scored Objects Table of Scored Objects object points used a thing a number a number Section 1(c) - Table of Scored Places Table of Scored Places loci points used a room a number a number Section 1(d) - Globals Achievement-Init is a number which varies. Achievement-Init is 0. The achievement maximum score is a number which varies. The achievement maximum score is 0. Chapter 2 - Rules Section 2(a) - Overriding the standard rules Procedural rule: substitute the announce the short score rule for the announce the score rule; substitute the announce the final score rule for the print final score rule. Section 2(b) - Inform 6 replacements Include (- Constant TASKS_PROVIDED; -) before the library. Include (- Replace AfterGameOver; -) before the library. Include (- [ AfterGameOver i; .RRQPL; L__M(##Miscellany,5); .RRQL; print "> "; say__p = 0; temp_global=0; #Ifdef TARGET_ZCODE; read buffer parse DrawStatusLine; #Ifnot; ! TARGET_GLULX KeyboardPrimitive(buffer, parse); #Endif; ! TARGET_ i=parse-->1; if (i==QUIT1__WD or QUIT2__WD) quit; if (i==RESTART__WD) @restart; if (i==RESTORE__WD) { RestoreSub(); jump RRQPL; } if (i==FULLSCORE1__WD or FULLSCORE2__WD && TASKS_PROVIDED==0) { new_line; (+ announce the achievements rule +)(); jump RRQPL; } if (deadflag==2 && i==AMUSING__WD && I7_Amusing_Provided()) { new_line; CarryOutActivity(AMUSING_ACT, 0); jump RRQPL; } if (i==UNDO1__WD or UNDO2__WD or UNDO3__WD) { #ifdef PREVENT_UNDO; print "The use of UNDO is forbidden in this game.^"; jump RRQPL; #endif; if (undo_flag==0) { L__M(##Miscellany,6); jump RRQPL; } if (undo_flag==1) jump UndoFailed2; #Ifdef TARGET_ZCODE; @restore_undo i; #Ifnot; ! TARGET_GLULX @restoreundo i; i = (~~i); #Endif; ! TARGET_ if (i==0) { .UndoFailed2; L__M(##Miscellany,7); } jump RRQPL; } L__M(##Miscellany,8); jump RRQL; ]; -) Section 2(c) - Inform 6 to display library messages Include (- [ FullScoreBegin; if (deadflag) (+ announce the died achievement score rule +)(); L__M(##FullScore, 1); ]; [ FullScoreThings; L__M(##FullScore, 2); ]; [ FullScoreRooms; L__M(##FullScore, 3); ]; -) Section 2(d) - Miscellaneous rules To pad (n - a number): let m be n; if n is less than 0 begin; let n be n multiplied by -1; let n be n multiplied by 10; end if; say " "; if n is less than 10 begin; say " "; otherwise; if n is less than 100 begin; say " "; otherwise; if n is less than 1000, say " "; end if; end if; say m; say " ". Section 2(e) - Full score replacement rules This is the announce the died achievement score rule: say "In that game you scored [score] out of a possible [achievement maximum score], in [turn count] turns.[line break]". To announce the beginning of full score: (- FullScoreBegin(); -). To announce the tabled part of full score: repeat through the Table of Achievements in used order begin; if the used entry is greater than 0 begin; let n be the points entry; pad n; say "for [message entry][line break]"; end if; end repeat. To announce the tabled objects of full score: let total be 0; repeat through the Table of Scored Objects begin; if the used entry is not 0, increase the total by the points entry; end repeat; if total is not 0 begin; pad total; say "for "; announce the end of objects in full score; end if. To announce the end of objects in full score: (- FullScoreThings(); -). To announce the tabled rooms of full score: let total be 0; repeat through the Table of Scored Places begin; if the used entry is not 0, increase the total by the points entry; end repeat; if total is not 0 begin; pad total; say "for "; announce the end of rooms in full score; end if. To announce the end of rooms in full score: (- FullScoreRooms(); -). To announce the end of full score: pad score; say "(out of [achievement maximum score])[line break]". To announce the no score: say "You have not received any points yet." Section 2(f) - Announce the achievements rule This is the announce the achievements rule: if the score is greater than 0 begin; announce the beginning of full score; announce the tabled part of full score; announce the tabled objects of full score; announce the tabled rooms of full score; announce the end of full score; otherwise; announce the no score; end if. Section 2(g) - Replacing "score" This is the announce the short score rule: say "You have so far scored [score] out of a possible [achievement maximum score], in [turn count] turn[s]." This is the announce the final score rule: say "In that game you scored [score] out of a possible [achievement maximum score], in [turn count] turn[s]." Section 2(h) - Score achievement To score the achievement with message (msg - text): choose row with message of msg in the Table of Achievements; if the used entry is 0 begin; change the used entry to the turn count; increase the score by the points entry; end if. Section 2(i) - Score objects To score found objects: repeat through the Table of Scored Objects begin; if the used entry is 0 begin; if the player encloses the object entry begin; change the used entry to the turn count; increase the score by the points entry; end if; end if; end repeat. Section 2(j) - Score rooms To score visited rooms: repeat through the Table of Scored Places begin; if the used entry is 0 begin; if the location is the loci entry begin; change the used entry to the turn count; increase the score by the points entry; end if; end if; end repeat. Section 2(k) - Initialization To perform initialization: let the total be 0; repeat through the Table of Scored Places begin; change the used entry to 0; increase the total by the points entry; if the loci entry is the location begin; change the used entry to -1; increase the score by the points entry; end if; end repeat; repeat through the Table of Scored Objects begin; change the used entry to 0; increase the total by the points entry; if the object entry is enclosed by the player begin; change the used entry to -1; increase the score by the points entry; end if; end repeat; repeat through the Table of Achievements begin; increase the total by the points entry; change the used entry to 0; end repeat; change the achievement maximum score to the total. Before printing the name of a room: if Achievement-Init is 0 begin; perform initialization; change Achievement-Init to 1; end if. Section 2(l) - Every turn Every turn (this is the scoring of rooms and objects rule): score found objects; score visited rooms. Section 2(m) - Decisions To decide whether the achievement (txt - text) is scored: repeat through the Table of Achievements begin; if the message entry is txt begin; if the used entry is not 0, decide yes; end if; end repeat; decide no. To decide whether the object (obj - a thing) is scored: repeat through the Table of Scored Objects begin; if the object entry is obj begin; if the used entry is not 0, decide yes; end if; end repeat; decide no. To decide whether the room (rm - a room) is scored: repeat through the Table of Scored Places begin; if the loci entry is rm begin; if the used entry is not 0, decide yes; end if; end repeat; decide no. Chapter 3 - Vocabulary Section 3(a) - Full score Understand "full score" or "full" or "fullscore" as requesting the full score. Requesting the full score is an action out of world. Carry out requesting the full score: follow the announce the achievements rule. Achievements end here. ---- Documentation ---- The Achievements extension allows for ease of scoring in a game. It allows for different achievements to be scored, as well as finding certain items and rooms. All the achievements, items, and rooms for scoring are managed through tables; the Table of Achievements, the Table of Scored Objects, and the Table of Scored Places respectively. The extension defines two global variables: 1. a number which varies called Achievement-Init. This is used for the extension to know if it has been initialized or not, since it needs to initialize itself when beginning the description of the first location in the game (when play begins does not work, unfortunately, since the location of the player during it is the dark room, not the real location). Initialization grants the points from the start room, if it has any, as well as of any objects enclosed by the player at the beginning of the game, if any have scores defined on them. The name has been chosen to minimize the risk of clashing with a variable in user code. 2. a number which varies called the achievement maximum score, which is automatically calculated at initialization time. To use the extension, you need to continue the tables you want to use. The Table of Scored Objects is defined as follows: Table of Scored Objects object points used a thing a number a number The Table of Scored Objects contain the objects for which a score will be given. The object column is the name of the object, the points column the value of the object, and the used column (which will be initialized to 0 at the start of the game) marks the fact of having received the points from the object. The Table of Scored Places is defined as follows: Table of Scored Places loci points used a room a number a number As with the Table of Scored Objects, the Table of Scored Places has the same function. The loci column defining the room to be scored replaces the object column. The used column will be initialized to 0 automatically. The Table of Achievements is defined as follows: Table of Achievements message points used text a number a number Again, the table looks like the previous tables, and again, the used column will be initialized to 0 automatically. The message contains the text which will be shown while listing the full score. To score an achievement, you need to use the following syntax: score the achievement with message "the message entry"; and the points will be added to the score. It is possible to test if an achievement, an object or a room has been scored, using the phrases the achievement "" is scored the item is scored the room is scored where is the message entry used to score the achievement, is the item tested for and is the room tested for. If needed, you may override the every turn rule, "scoring of rooms and objects". The extension replaces the score and the full score handling of Inform 7, including the final score displaying, to manage the listing of scores from the tables, and contains a little bit of code in Inform 6 - code neutral to the Z-machine and Glulx. Example: ** Where ever thou art - Demonstrating the use of achievements, locations scored and items scored. "Where ever thou art" Include Achievements by Mikael Segercrantz. Let's create the three rooms first. The entrance hall is a room. The basement is a room. The dining hall is a room. Add a door and the connections: A wooden door is a door. It is west of the entrance hall and east of the dining hall. It is closed and openable. The basement is below the entrance hall. Add some treasure: A baseball cap is a thing. Some crates are in the basement. They are fixed in place. Instead of searching the crates for the first time: now the baseball cap is in the basement; say "Tucked behind crates of various things, you find a baseball cap!" After opening the wooden door, score the achievement with message "finding the way to the dining hall". And the tables: Table of Achievements (continued) used points message 0 10 "finding the way to the dining hall" Table of Scored Places (continued) used points loci 0 5 basement 0 5 dining hall Table of Scored Objects (continued) used points object 0 5 baseball cap Initialize status line: When play begins: change the right hand status line to "[score] out of [achievement maximum score]". Ending the game: Every turn: if the score is the achievement maximum score, end the game in victory. And finally the testing command: Test me with " open door / w / e / d / search crates / take cap ".